前面幾篇講到了元件,並介紹元件之間由外而內資料傳遞的屬性 props
還有由內而外傳遞的事件 emit
元件也不只可以重複的讓我們來做使用,如果今天一個元件我們只想要替換部分內容也是可行的
這時候就要來介紹 slot
了,也就是替換部分內容
首先先照前面的方式建立一個元件:
<div id="app">
<h2>沒有插槽可替換的狀態</h2>
<no-slot-component></no-slot-component>
</div>
<script type="text/x-template" id="noSlotComponent">
<div class="alert alert-warning">
<h6>我是一個元件</h6>
<p>
這沒有插槽。
</p>
</div>
</script>
<script>
Vue.component('no-slot-component', {
template: '#noSlotComponent',
});
var app = new Vue({
el: '#app',
data: {}
});
</script>
這時候如果在 no-slot-component
元件內,加上一些內容:
<div id="app">
<h2>沒有插槽可替換的狀態</h2>
<no-slot-component>
<p>這是一段置換的內容</p>
</no-slot-component>
</div>
會發現內容根本沒有被呈現出來
如果今天換成另外一種情況:
<div id="app">
<h2>Slot 基礎範例</h2>
<single-slot-component>
<p>使用這段取代原本的 Slot。</p>
</single-slot-component>
</div>
<script type="text/x-template" id="singleSlotComponent">
<div class="alert alert-warning">
<h6>我是一個元件</h6>
<div>
如果沒有內容,則會顯示此段落。
</div>
</div>
</script>
<script>
Vue.component('single-slot-component', {
template: '#singleSlotComponent',
})
var app = new Vue({
el: '#app',
data: {}
});
</script>
我們在 single-slot-component
元件內新增了一個 <p>
,然後在 x-template
的地方新增一個 <slot>
標籤:
<script type="text/x-template" id="singleSlotComponent">
<div class="alert alert-warning">
<h6>我是一個元件</h6>
<div>
如果沒有內容,則會顯示此段落。
</div>
<slot></slot>
</div>
</script>
會發現內容就被呈現出來了,有趣的是當我們替換成下面的樣子時:
<script type="text/x-template" id="singleSlotComponent">
<div class="alert alert-warning">
<h6>我是一個元件</h6>
<slot>
如果沒有內容,則會顯示此段落。
</slot>
</div>
</script>
如果 single-slot-component
元件沒有任何內容時,就會顯示 <slot>
標籤內的內容,如果有的話,就是呈現插入的內容
如果我們想要多個部分內容置換時:
<div id="app">
<h2>具名插槽</h2>
<named-slot-component>
<header>替換的 Header</header>
<template>替換的 Footer</template>
<template>按鈕內容</template>
</named-slot-component>
</div>
<script type="text/x-template" id="namedSlotComponent">
<div class="card my-3">
<div class="card-header">
<div>這段是預設的文字</div>
</div>
<div class="card-body">
<slot>
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
</slot>
<a href="#" class="btn btn-primary">
<div>spanGo somewhere<div>
</a>
</div>
<div class="card-footer">
<div>這是預設的 Footer</div>
</div>
</div>
</script>
<script>
Vue.component('named-slot-component', {
template: '#namedSlotComponent',
});
var app = new Vue({
el: '#app',
data: {}
});
</script>
我們已經把要置換的內容放在 named-slot-component
元件裡面了,這時候我們只要在 x-template
的地方,把要置換的部分對應起來,這時候除了用 slot
標籤之外,還要賦予 name
這個屬性,值可以自定義,如下:
<script type="text/x-template" id="namedSlotComponent">
<div class="card my-3">
<div class="card-header">
<slot name="header">這段是預設的文字</slot>
</div>
<div class="card-body">
<slot>
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
</slot>
<a href="#" class="btn btn-primary">
<div>spanGo somewhere<div>
</a>
</div>
<div class="card-footer">
<div>這是預設的 Footer</div>
</div>
</div>
</script>
然後在 named-slot-component
元件置換內容的部分,新增 slot
屬性,值就是我們剛剛自定義 name
屬性的值
<div id="app">
<h2>具名插槽</h2>
<named-slot-component>
<header slot="header">替換的 Header</header>
<template>替換的 Footer</template>
<template>按鈕內容</template>
</named-slot-component>
</div>
這時候內容就會替換上去了,其他地方也是一樣的,但是有發現我元件內的置換內容有用到 <template>
標籤,這是不會被輸出的,所以置換時並不會去動到原有的 HTML
結構,可以打開開發人員工具就知道了